﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Teal.Compiler {

    /// <summary>
    /// 表示成员类型的枚举。
    /// </summary>
    [Flags]
    public enum MemberType {

        /// <summary>
        /// 表示一个命名空间。
        /// </summary>
        @namespace = 0,

        /// <summary>
        /// 表示一个扩展。
        /// </summary>
        extension = 1 << 0,

        /// <summary>
        /// 表示一个类。
        /// </summary>
        @class = 1 << 1,

        /// <summary>
        /// 表示一个结构。
        /// </summary>
        @struct = 1 << 2,

        /// <summary>
        /// 表示一个接口。
        /// </summary>
        @interface = 1 << 3,

        /// <summary>
        /// 表示一个枚举。
        /// </summary>
        @enum = 1 << 4,

        /// <summary>
        /// 表示一个泛型参数。
        /// </summary>
        typeParameter = 1 << 5,

        /// <summary>
        /// 表示一个字段。
        /// </summary>
        field = 1 << 6,

        /// <summary>
        /// 表示一个属性。
        /// </summary>
        property = 1 << 7,

        /// <summary>
        /// 表示一个索引访问器。
        /// </summary>
        indexer = 1 << 8,

        /// <summary>
        /// 表示一个方法。
        /// </summary>
        method = 1 << 9,

        /// <summary>
        /// 表示一个构造函数。
        /// </summary>
        constructor = 1 << 10,

        /// <summary>
        /// 表示一个操作符重载函数。
        /// </summary>
        @operator = 1 << 12,

        /// <summary>
        /// 表示一个特殊类型。
        /// </summary>
        specailType = 1 << 13,

        /// <summary>
        /// 表示一个约束类型。
        /// </summary>
        constraintType = 1 << 14,
        
        /// <summary>
        /// 表示错误的类型。
        /// </summary>
        errorType = 1 << 16,

    }

    /// <summary>
    /// 对 <see cref="MemberType"/> 的扩展。
    /// </summary>
    public static class MemberTypeExtensions {

        /// <summary>
        /// 获取 MemberType 对应的名字。
        /// </summary>
        /// <param name="memberType"></param>
        /// <returns></returns>
        public static string getName(this MemberType memberType) {
            return memberType.ToString();
        }

        /// <summary>
        /// 获取 MemberType 对应的可读名字。
        /// </summary>
        /// <param name="memberType"></param>
        /// <returns></returns>
        public static string getReadableName(this MemberType memberType) {
            switch (memberType) {
                case MemberType.@class:
                    return "类";
                case MemberType.@struct:
                    return "结构";
                case MemberType.@interface:
                    return "接口";
                case MemberType.@enum:
                    return "枚举";
                case MemberType.@extension:
                    return "扩展";
                case MemberType.@namespace:
                    return "命名空间";
                case MemberType.@method:
                    return "方法";
                case MemberType.@property:
                    return "属性";
                case MemberType.@indexer:
                    return "索引器";
                case MemberType.@field:
                    return "字段";
                case MemberType.typeParameter:
                    return "泛型形参";
                case MemberType.constructor:
                    return "构造函数";
                case MemberType.@operator:
                    return "操作符重载";
                case MemberType.specailType:
                    return String.Empty;
                case MemberType.constraintType:
                    return "约束";
                default:
                    throw new Unreachable();
            }
        }

        /// <summary>
        /// 判断指定的成员类型是否可重载。
        /// </summary>
        /// <param name="memberType"></param>
        /// <returns></returns>
        public static bool isOverloadable(this MemberType memberType) {
            return (memberType & (MemberType.method | MemberType.constructor | MemberType.@operator | MemberType.indexer)) != 0;
        }

    }

}
